const path = require('path')
const webpack = require('webpack')
const { merge } = require('webpack-merge')
const { VueLoaderPlugin } = require('vue-loader')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const Dotenv = require('dotenv-webpack')
const TerserPlugin = require('terser-webpack-plugin')
const IgnoreEmitPlugin = require('ignore-emit-webpack-plugin')
const ZipPlugin = require('zip-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const projectRoot = path.resolve(__dirname, '../../')

// V3 manifest转换插件
class ManifestV3TransformPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync('ManifestV3TransformPlugin', (compilation, callback) => {
      const manifestAsset = compilation.assets['manifest.json']
      if (!manifestAsset) {
        callback()
        return
      }

      try {
        const manifestContent = manifestAsset.source()
        const manifest = JSON.parse(manifestContent)
        
        // 清理CSP中的unsafe-eval和外部域名（V3不允许）
        let cleanedCSP = manifest.content_security_policy || "script-src 'self'; object-src 'self'"
        if (typeof cleanedCSP === 'string') {
          // 移除unsafe-eval
          cleanedCSP = cleanedCSP.replace(/'unsafe-eval'\s*/g, '')
          // 移除外部队名（只允许'self'和本地资源）
          cleanedCSP = cleanedCSP.replace(/script-src\s+[^;]+/, "script-src 'self'")
          // 清理多余的分号
          cleanedCSP = cleanedCSP.replace(/;\s*;/g, ';').replace(/^;|;;/g, '').trim()
        } else {
          cleanedCSP = "script-src 'self'; object-src 'self'"
        }
        
        // 转换manifest到V3格式
        const v3Manifest = {
          ...manifest,
          manifest_version: 3,
          // 转换background
          background: {
            service_worker: 'background.js',
            type: 'module'
          },
          // 转换browser_action到action
          action: manifest.browser_action || {
            default_icon: 'icon.png',
            default_popup: 'index.html'
          },
          // 移除browser_action
          browser_action: undefined,
          // 分离permissions和host_permissions
          permissions: manifest.permissions?.filter(p => 
            !p.includes('://') && p !== 'webRequest' && p !== 'webRequestBlocking'
          ) || [],
          host_permissions: manifest.permissions?.filter(p => 
            p.includes('://') || p === 'http://*/*' || p === 'https://*/*'
          ) || ['http://*/*', 'https://*/*'],
          // 转换web_accessible_resources
          web_accessible_resources: [{
            resources: manifest.web_accessible_resources || [],
            matches: ['http://*/*', 'https://*/*']
          }],
          // 转换content_security_policy（移除unsafe-eval）
          content_security_policy: {
            extension_pages: cleanedCSP
          }
        }

        // 清理undefined值
        Object.keys(v3Manifest).forEach(key => {
          if (v3Manifest[key] === undefined) {
            delete v3Manifest[key]
          }
        })

        const newManifestContent = JSON.stringify(v3Manifest, null, 2)
        compilation.assets['manifest.json'] = {
          source: () => newManifestContent,
          size: () => newManifestContent.length
        }
        
        callback()
      } catch (error) {
        callback(error)
      }
    })
  }
}

const entry = (function() {
  const filesToPack = [
    'background.js',
    'popup.js',
    'content.js',
    'segmenftfault.js',
    'editor.js',
    'inject.js',
    'styles.scss',
    'page.js',
    'api.js',
    'viewer.js',
    'autoformat.js',
    'template.js',
  ]

  function replaceSuffixes(file) {
    return file.replace('scss', 'css')
  }

  return filesToPack.reduce(
    (o, file) =>
      Object.assign(o, {
        [replaceSuffixes(file)]: `./src/${file}`,
      }),
    {}
  )
})()

// V3版本入口文件替换
const getV3Entry = (baseEntry) => {
  const v3Entry = {}
  
  // 手动定义V3版本的入口文件
  v3Entry['background.js'] = './src/background-v3.js'
  v3Entry['popup.js'] = './src/popup.js'
  v3Entry['content.js'] = './src/content-v3.js'
  v3Entry['segmenftfault.js'] = './src/segmenftfault.js'
  v3Entry['editor.js'] = './src/editor.js'
  v3Entry['inject.js'] = './src/inject.js'
  v3Entry['styles.css'] = './src/styles.scss'
  v3Entry['page.js'] = './src/page.js'
  v3Entry['api.js'] = './src/api.js'
  v3Entry['viewer.js'] = './src/viewer.js'
  v3Entry['autoformat.js'] = './src/autoformat.js'
  v3Entry['template.js'] = './src/template.js'
  
  return v3Entry
}

module.exports = env => {
  const prodMode = env.production
  const isV3 = env.v3
  const prodConfigs = {
    mode: 'production',
    resolve: {
      alias: {
        vue: isV3 ? 'vue/dist/vue.runtime.min.js' : 'vue/dist/vue.min.js',
      },
    },
    optimization: {
      minimize: true,
      minimizer: [
        new TerserPlugin({
          test: /\.js(\?.*)?$/i,
          exclude: /\.min\.js$/i,
          terserOptions: {
            compress: {
              drop_console: false, // 保留console.log
              drop_debugger: false, // 保留debugger语句
            },
            mangle: {
              reserved: ['console', 'log', 'error', 'warn'], // 保留console相关函数名
            },
          },
        }),
      ],
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: '"production"',
          WECHAT_ENV: '"production"',
          MANIFEST_V3: isV3 ? '"true"' : '"false"'
        },
      }),
      new ZipPlugin({
        path: path.resolve(__dirname, 'zip'),
        filename: isV3 ? 'WechatSync-v3.zip' : 'WechatSync.zip',
      }),
    ],
  }
  const devConfigs = {
    mode: 'development',
    devtool: 'inline-source-map',
    resolve: {
      alias: {
        vue: isV3 ? 'vue/dist/vue.js' : 'vue/dist/vue.js',
      },
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: '"development"',
          MANIFEST_V3: isV3 ? '"true"' : '"false"'
        },
      }),
    ],
  }

  const commonConfigs = {
    entry: isV3 ? {
      'background.js': './src/background-v3.js',
      'popup.js': './src/popup.js',
      'popup-init.js': './src/popup-init.js',
      'content.js': './src/content-v3.js',
      'content-float.js': './src/content-float.js',
      'segmenftfault.js': './src/segmenftfault.js',
      'editor.js': './src/editor.js',
      'inject.js': './src/inject.js',
      'styles.css': './src/styles.scss',
      'page.js': './src/page.js',
      'api.js': './src/api.js',
      'viewer.js': './src/viewer.js',
      'autoformat.js': './src/autoformat.js',
      'template.js': './src/template.js'
    } : entry, // 直接定义V3入口文件
    output: {
      filename: '[name]',
      path: path.resolve(__dirname, 'dist'),
      clean: true,
    },
    module: {
      rules: [
        {
          test: /\.(sa|sc|c)ss$/i,
          use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
        },
        {
          test: /\.(png|svg|jpg|jpeg|gif)$/i,
          type: 'asset/resource',
        },
        {
          test: /\.(woff|woff2|eot|ttf|otf)$/i,
          type: 'asset/resource',
        },
        {
          test: /\.js?$/,
          loader: 'babel-loader',
          exclude: file =>
            (/node_modules/.test(file) && !/\.vue\.js/.test(file)) ||
            /\.min\.js$/i.test(file),
          options: {
            rootMode: 'upward',
          },
        },
        {
          test: /\.vue$/,
          loader: 'vue-loader',
        },
      ],
    },
    plugins: [
      new MiniCssExtractPlugin({
        filename: '[name].css',
      }),
      new IgnoreEmitPlugin(/\.omit$/),
      new CopyWebpackPlugin({
        patterns: [
          {
            from: 'src/copied',
          },
        ],
      }),
      new VueLoaderPlugin(),
      new Dotenv({
        path: path.resolve(
          projectRoot,
          prodMode ? '.env.production' : '.env.development'
        ),
        safe: true,
      }),
      // V3模式下添加manifest转换插件
      ...(isV3 ? [new ManifestV3TransformPlugin()] : []),
    ],
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src'),
      },
    },
  }

  return merge(commonConfigs, prodMode ? prodConfigs : devConfigs)
}
